#include <jni.h>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <android/log.h>
#include "pthread.h"
#include "unistd.h"

#define LOG_TAG "System.out"//System.out可以修改为其他字符串，该字符串会作为输出日志的TAG。
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

class LocalSocketClient {

    public:int connect_fd = -1;
    private:pthread_t mThreadRecv;//接收线程

    static void *recvCB(void* parm){
        auto client = (LocalSocketClient*)parm;
        char recv_buff[1024];

        while (!(client->isClose())){
            memset(recv_buff,0,1024);
            int num = recv(client->connect_fd,recv_buff, sizeof(recv_buff),0);
            //recv函数是堵塞的

            if (num < 0){
                LOGI("客户端数据错误，检查连接是否正常：%d",num);
            }else{
                LOGI("客户端收到数据内容:%s",recv_buff);
            }
        }
    }

    public:int doConnect(const char address[]) {

        connect_fd = socket(AF_UNIX,SOCK_STREAM,0);
        if (connect_fd < 0){
            LOGI("init socket fail");
            return 1;
        }

        sockaddr_un srv_addr{};
        memset(&srv_addr,0,sizeof(srv_addr));
        srv_addr.sun_path[0] = '\0';
        strcpy(srv_addr.sun_path + 1, address);

        srv_addr.sun_family = AF_UNIX;

        int nameLen = strlen(address);
        int len = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);

        int ret = connect(connect_fd,(struct sockaddr*)&srv_addr, len);
        if (ret == -1){
            LOGI("connect socket fail:%d",ret);
            return -1;
        }
        LOGI("connect success,start thread");
        pthread_create(&mThreadRecv,NULL,recvCB,this);

        return 0;
    }

    public:bool isClose() const{
        return connect_fd <= 0;
    }

    public:void close(){
        ::close(connect_fd);//关闭连接
        connect_fd = -1;
    }

    public:void send(char msg[]){
        ::send(connect_fd,msg, strlen(msg),0);
    }
};